package com.ddz.service;

import com.ddz.model.Poker;
import com.ddz.model.Room;
import com.ddz.model.User;
import org.json.JSONArray;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.Session;

/**
 * 房间管理类
 *
 * 管理服务器上所有房间
 */
public class GameRoomManager {

    // 保存所有房间，每个房间的玩家是一个 Map，key 是 Session，value 是 User
    private static Map<String, Room> rooms = new ConcurrentHashMap<>();

    // 将玩家加入房间
    public static void addPlayerToRoom(String roomId, User user, Session session) {
        // 为每个房间创建一个新的玩家列表，并将玩家与其对应的 Session 存储在 Map 中
        rooms.computeIfAbsent(roomId, k -> new Room());
        if (rooms.containsKey(roomId)) {
            rooms.get(roomId).adduser(session, user);
        }
    }

    // 从房间中移除玩家
    public static void removePlayerFromRoom(String roomId, String UserId) {
        try {
            Map<Session, User> players = rooms.get(roomId).getUserMap();
            if (players != null) {
                // 遍历所有玩家，找到对应 playerId 的玩家并移除
                players.entrySet().removeIf(entry -> entry.getValue().getUserId().equals(UserId));
            }
        }catch (Exception e){
            System.out.println("移除玩家失败！");
            e.printStackTrace();
        }
    }

    // 广播消息给房间内的所有玩家
    public static void broadcastMessage(String roomId, String message) {
        try {
            Map<Session, User> players = rooms.get(roomId).getUserMap();
            if (players != null) {
                for (Map.Entry<Session, User> entry : players.entrySet()) {
                    Session session = entry.getKey();
                    try {
                        session.getBasicRemote().sendText(message);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }catch (Exception e){
            System.out.println("发送消息时发生错误！");
            e.printStackTrace();
        }
    }

    // 给指定玩家发送消息
    public static void sendMessageToPlayer(String roomId, String playerId, String message) {
        try {
            Map<Session, User> players = rooms.get(roomId).getUserMap();
            if (players != null) {
                // 遍历房间内的玩家，找到匹配 playerId 的玩家并发送消息
                for (Map.Entry<Session, User> entry : players.entrySet()) {
                    User player = entry.getValue();
                    if (player.getUserId().equals(playerId)) {
                        try {
                            // 通过 session 给该玩家发送消息
                            entry.getKey().getBasicRemote().sendText(message);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        break;  // 找到玩家并发送消息后，可以退出循环
                    }
                }
            }
        }catch (Exception e){
            System.out.println("给指定玩家发送消息时发送错误！");
            e.printStackTrace();
        }
    }

    // 删除房间及其所有玩家
    public static void removeRoom(String roomId) {
        try {
            if (rooms.containsKey(roomId)) {
                Map<Session, User> players = rooms.remove(roomId).getUserMap();
                if (players != null) {
                    // 关闭房间内所有玩家的连接
                    for (Session session : players.keySet()) {
                        try {
                            if (session.isOpen()) {
                                session.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            else {
                System.out.println("删除房间失败！无此房间！");
            }
        }catch (Exception e){
            System.out.println("删除房间时失败！");
            e.printStackTrace();
        }
    }

    // 获取房间的玩家数量
    public static int getRoomPlayerCount(String roomId) {
        try {
            if (rooms.containsKey(roomId)) {
                return rooms.get(roomId).getRoomPlayerCount();
            }
            return 0;
        }catch (Exception e){
            System.out.println("获取玩家数量失败！");
            e.printStackTrace();
        }
        return 0;
    }

    // 获取房间内指定玩家的 Player 对象
    public static User getPlayerInRoom(String roomId, String userId) {
        try {
            if (rooms.containsKey(roomId)) {
                List<User> ls = getAllPlayersInRoom(roomId);
                for (User user : ls) {
                    if (user.getUserId().equals(userId)) {
                        return user;
                    }
                }
            }
        }catch (Exception e){
            System.out.println("获取指定玩家时失败！");
            e.printStackTrace();
        }
        return null;
    }

    // 获取房间内所有玩家对象的列表
    public static List<User> getAllPlayersInRoom(String roomId) {
        if (rooms.containsKey(roomId)) {
            return rooms.get(roomId).getAllPlayersInRoom();
        }
        return new ArrayList<>();
    }

    // 指定的房间进行发牌
    public static void Room_dealPokers(String roomId) {
        try {
            if (rooms.containsKey(roomId)){
                rooms.get(roomId).dealPokers();
            }else {
                throw new Exception("无此房间！");
            }
        }catch (Exception e){
            System.out.println("无此房间！");
            e.printStackTrace();
        }
    }

    // 获取玩家手牌信息
    public static JSONArray Room_userPokers(String roomId, String userId) {
        try {
            if (rooms.containsKey(roomId)) {
                List<String> list = rooms.get(roomId).userPokers(userId);
                JSONArray jsonArray = new JSONArray();
                for (String pokerid : list) {
                    jsonArray.put(pokerid);
                }
                return jsonArray;
            }
            else {
                return new JSONArray();
            }
        }catch (Exception e){
            System.out.println("获取玩家手牌信息时失败！");
            e.printStackTrace();
        }
        return new JSONArray();
    }

    // 设置房间信息
    public static void Room_setinfo(String roomId, String key, String value) {
        try {
            if (rooms.containsKey(roomId)) {
                rooms.get(roomId).setRoominfo(key, value);
            }
            else {
                System.out.println("无此房间！");
            }
        }catch (Exception e){
            System.out.println("设置房间信息时失败！");
            e.printStackTrace();
        }
    }

    // 获取房间信息
    public static String Room_getinfo(String roomId, String key) {
        try {
            if (rooms.containsKey(roomId)) {
                return rooms.get(roomId).getRoominfo(key);
            }
            else {
                return "";
            }
        }catch (Exception e){
            System.out.println("获取房间信息时失败！");
            e.printStackTrace();
        }
        return "";
    }

    // 判断该玩家是否能出牌
    public static boolean Room_judge_current(String roomId, String userId) {
        return rooms.get(roomId).judge_current(userId);
    }

    // 设置下一位玩家出牌
    public static void Room_next_user(String roomId) {
        rooms.get(roomId).next_user();
    }

    // 设置当前出牌玩家
    public static void Room_setcurrent_user(String roomId, String userid) {
        rooms.get(roomId).setcurrent_user(userid);
    }

    // 获取当前出牌玩家ID
    public static String Room_getcurrent_user(String roomId) {
        if (rooms.containsKey(roomId)) {
            return rooms.get(roomId).current_user();
        }
        return "";
    }

    // 为玩家添加地主牌
    public static void Room_addloadPokers(String roomId, String userId) {
        rooms.get(roomId).addloadPokers(userId);
    }

    // 删除玩家牌
    public static void Room_delPokers(String roomId, String userId, List<Poker> pokers) {
        rooms.get(roomId).delPokers(userId, pokers);
    }

    // 增加跳过数量
    public static void Room_passadd(String roomId) {
        rooms.get(roomId).passadd();
    }

    // 获取跳过数量
    public static int Room_getpassnum(String roomId) {
        return rooms.get(roomId).getpassnum();
    }

    // 归零跳过数量
    public static void Room_clear_passnum(String roomId) {
        rooms.get(roomId).clear_passnum();
    }
}
